package yiran.agift.gui;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.ItemStack;
import yiran.agift.AGift;
import yiran.agift.lang.LangHelper;
import java.util.List;
public class aGiftGUIListener implements Listener {

    /**
     * 处理玩家点击物品栏事件
     * 该方法主要用于响应玩家在特定物品栏界面的点击事件，以实现不同的功能
     *
     * @param event 物品栏点击事件对象，包含事件的详细信息，如点击的物品栏类型、点击位置等
     */
    @EventHandler
    public void onInventoryClick(InventoryClickEvent event) {
        // 调用处理礼物查看界面的方法
        GiftViewGUI(event);
        // 调用处理邮箱界面的方法
        MailboxGUI(event);
        // 调用处理礼物创建和编辑界面的方法
        GiftCreateAndEditGUI(event);
    }

    /**
     * 处理礼物创建和编辑界面的点击事件
     * 此方法旨在响应玩家在礼物创建或编辑界面中的操作
     *
     * @param event InventoryClickEvent类型的事件，表示玩家在界面中点击了一个槽位
     */
    private void GiftCreateAndEditGUI(InventoryClickEvent event) {
        // 获取界面标题，用于判断当前界面是否为礼物创建或编辑界面
        String title = event.getView().getTitle();

        // 检查界面标题是否包含创建或编辑礼物的特定前缀
        if (title.contains(LangHelper.getString("gui.create_title_prefix")) ||
                title.contains(LangHelper.getString("gui.edit_title_prefix"))) {
            // 检查玩家是否点击了保存按钮（假设保存按钮位于第53个槽位）
            if (event.getSlot() == 53) {
                // 获取点击事件的玩家对象
                Player player = (Player) event.getWhoClicked();

                // 根据界面标题提取礼物名称，通过移除标题中的创建前缀实现
                String giftName = title.replace(LangHelper.getString("gui.create_title_prefix"), "");

                // 解析标题中的礼物ID，用于编辑已存在的礼物
                int giftId = parseGiftIdFromTitle(title);

                // 调用礼物编辑器的保存方法，将玩家编辑的礼物信息保存到服务器
                AGift.getInstance().getGiftEditor().handleSave(player, event.getInventory(), giftName, giftId);

                // 关闭玩家的界面
                player.closeInventory();

                // 取消点击事件，防止默认行为发生
                event.setCancelled(true);
            }
        }
    }

    /**
     * 处理礼物视图中的库存点击事件
     * 此方法旨在响应玩家在礼物视图界面中的点击操作，确保玩家只能在特定条件下关闭界面
     *
     * @param event 库存点击事件，包含事件相关的信息如点击的物品、事件的玩家等
     */
    private void GiftViewGUI(InventoryClickEvent event) {
        // 检查事件视图标题是否包含特定前缀，如果不包含则直接返回，不进行后续处理
        if (!event.getView().getTitle().contains(LangHelper.getString("gui.view_title_prefix"))) {
            return;
        }
        // 取消点击事件的默认行为，防止物品被移动或交互
        event.setCancelled(true);
        // 检查玩家是否点击了界面的关闭按钮（假设关闭按钮位于第53槽）
        if (event.getSlot() == 53) {
            // 如果玩家点击了关闭按钮，则关闭玩家的当前视图
            event.getWhoClicked().closeInventory();
        }
        // 以下两行代码未使用，可能是未完成的功能或占位符
        // 获取视图标题，可能是为了日志记录或调试
        event.getView().getTitle();
        // 获取语言字符串，可能是为了界面显示或提示
        LangHelper.getString("mailbox.title");
    }

    /**
     * 处理邮箱界面的点击事件
     *
     * @param event InventoryClickEvent类型的事件对象，包含点击事件的相关信息
     */
    private void MailboxGUI(InventoryClickEvent event) {
        // 检查界面标题是否与邮箱界面标题匹配，如果不匹配则直接返回
        if (!event.getView().getTitle().equals(LangHelper.getString("mailbox.title"))) {
            return;
        }

        // 取消默认的点击事件行为，以防止不希望的界面关闭或其他默认行为
        event.setCancelled(true);

        // 获取点击事件的玩家对象
        Player player = (Player) event.getWhoClicked();

        // 获取点击的槽位编号
        int slot = event.getSlot();

        // 如果点击的是全部领取按钮，则执行全部领取操作并关闭界面
        if (slot == 49) {
            claimAllGifts(player);
            player.closeInventory();
            return;
        }

        // 如果点击的是关闭按钮，则直接关闭界面
        if (slot == 53) {
            player.closeInventory();
            return;
        }

        // 如果点击的是礼物槽位，则进一步处理
        if (slot < 45) {
            ItemStack item = event.getCurrentItem();

            // 检查点击的物品是否为礼物箱，如果是则进一步处理
            if (item != null && item.getType() == Material.CHEST) {
                int giftId = parseGiftIdFromItem(item);

                // 如果解析到有效的礼物ID，则执行领取操作并移除该槽位的物品
                if (giftId != -1) {
                    claimGift(player, giftId);
                    event.getInventory().setItem(slot, null);
                }
            }
        }
    }

    /**
     * 处理玩家关闭背包界面事件
     * 该事件监听主要用于在玩家关闭特定标题的背包界面时保存玩家的编辑内容
     *
     * @param event 背包关闭事件，包含关闭背包的玩家和背包信息
     */
    @EventHandler
    public void onInventoryClose(InventoryCloseEvent event) {
        // 获取背包界面的标题
        String title = event.getView().getTitle();

        // 检查背包标题是否包含创建或编辑礼物的标识
        if (title.contains(LangHelper.getString("gui.create_title_prefix")) ||
                title.contains(LangHelper.getString("gui.edit_title_prefix"))) {

            // 获取操作背包的玩家
            Player player = (Player) event.getPlayer();

            // 从标题中提取礼物名称
            String giftName = title.replace(LangHelper.getString("gui.create_title_prefix"), "");

            // 解析标题中的礼物ID
            int giftId = parseGiftIdFromTitle(title);

            // 调用礼物编辑器的保存方法，保存玩家的编辑内容
            AGift.getInstance().getGiftEditor().handleSave(player, event.getInventory(), giftName, giftId);
        }
    }

    /**
     * 玩家领取邮箱中的所有礼物
     * 此方法首先获取玩家邮箱中的所有礼物ID，然后尝试领取每个礼物
     * 领取成功后，增加计数器claimed，最后清空邮箱并发送消息给玩家通知领取结果
     *
     * @param player 玩家对象，用于获取玩家唯一标识和发送消息
     */
    private void claimAllGifts(Player player) {
        // 获取玩家邮箱中的所有礼物ID
        List<Integer> giftIds = AGift.getInstance()
            .getMailboxManager()
            .getPlayerMailbox(player.getUniqueId());
        int claimed = 0;
        // 遍历每个礼物ID尝试领取
        for (int giftId : giftIds) {
            if (claimGift(player, giftId)) {
                claimed++;
            }
        }
        // 清空玩家邮箱
        AGift.getInstance().getMailboxManager().clearMailbox(player.getUniqueId());
        // 发送消息通知玩家领取结果
        player.sendMessage(LangHelper.getString("mailbox.claimed_all").replace("%count%", String.valueOf(claimed)));
    }

    /**
     * 玩家领取礼物的方法
     *
     * @param player 玩家对象，用于识别哪个玩家在领取礼物
     * @param giftId 礼物ID，用于确定要领取的礼物种类
     * @return boolean 表示礼物是否成功被领取如果礼物不存在，则返回false；否则，返回true
     */
    private boolean claimGift(Player player, int giftId) {
        // 根据礼物ID获取礼物物品数组
        ItemStack[] giftItems = AGift.getInstance().getGiftManager().getGift(giftId);
        // 如果礼物不存在，返回false
        if (giftItems == null) return false;

        // 遍历礼物中的每个物品
        for (ItemStack item : giftItems) {
            // 如果物品不为空，则将其添加到玩家的背包中
            if (item != null) {
                player.getInventory().addItem(item.clone());
            }
        }

        // 清除玩家的礼物，表示该礼物已经被领取
        AGift.getInstance().getMailboxManager().clearGift(player.getUniqueId(), giftId);

        // 礼物成功领取，返回true
        return true;
    }

    /**
     * 从物品堆中解析礼物ID
     * 此方法旨在从给定的ItemStack对象中提取礼物的唯一ID这个ID被期望存在于物品的描述中，
     * 如果物品为空、没有元数据或者没有描述，则返回-1如果描述中包含"ID:"，则尝试解析其后的数字作为礼物ID
     * 如果解析失败，则返回-1
     *
     * @param item ItemStack对象，代表一个游戏中的物品
     * @return 礼物的唯一ID，如果无法解析或物品无效，则返回-1
     */
    private int parseGiftIdFromItem(ItemStack item) {
        // 检查物品是否为空、是否有元数据、是否有描述
        if (item == null || !item.hasItemMeta() || !item.getItemMeta().hasLore()) {
            return -1;
        }
        // 遍历物品描述的每一行，寻找包含"ID:"的行
        for (String line : item.getItemMeta().getLore()) {
            if (line.contains("ID:")) {
                try {
                    // 尝试解析"ID:"后的字符串为整数，作为礼物ID
                    return Integer.parseInt(line.split("ID:")[1].trim());
                } catch (NumberFormatException e) {
                    // 如果解析失败，返回-1表示无效的ID
                    return -1;
                }
            }
        }
        // 如果遍历完所有描述行都没有找到"ID:"，返回-1
        return -1;
    }

    /**
     * 从标题中解析礼物ID
     * <p>
     * 此方法尝试从给定的标题字符串中解析出礼物ID标题应以特定前缀开始，
     * 该前缀是通过LangHelper.getString("gui.edit_title_prefix")获取的
     * 如果标题包含该前缀，则提取前缀之后的部分并将其解析为整数（礼物ID）
     * 如果标题不包含前缀，或者解析过程中出现异常，则返回-1表示失败
     *
     * @param title 礼物标题，可能包含礼物ID
     * @return 解析出的礼物ID，如果解析失败则返回-1
     */
    private int parseGiftIdFromTitle(String title) {
        try {
            // 检查标题是否包含必要的前缀
            if (title.contains(LangHelper.getString("gui.edit_title_prefix"))) {
                // 获取前缀字符串
                String prefix = LangHelper.getString("gui.edit_title_prefix");
                // 从标题中提取ID部分，去除前缀并修剪空格
                String idPart = title.substring(prefix.length()).trim();
                // 将提取的ID部分转换为整数并返回
                return Integer.parseInt(idPart);
            }
        } catch (Exception e) {
            // 异常情况下，返回-1表示解析失败
            return -1;
        }
        // 如果执行到此处，也表示解析失败，返回-1
        return -1;
    }

}
